package ub.pis.net;

import java.io.*;
import java.net.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Clase goear, busca las canciones, parsea la web (html) para encontrar el link
 * del primer resultado de la busqueda y encuentra el link directo hasta el archivo
 * mp3 correspondiente.
 * @author nagash
 *
 */
public class Goear {

	private final String search_url = "http://goear.com/search.php?q=";
	private final String regular_exp = "<div\\s+style=[^>]*>" + ".*?href=\""
			+ "([^\"]+)" + "\"[^>]*class=";

	private String mp3_url;
	private String artist;
	private String title;

	/**
	 * Constructor
	 * @param artist
	 * @param title
	 */
	public Goear(String artist, String title) {
		this.artist = artist;
		this.title = title;
		this.mp3_url = null;
	}
	
	public void setTitle(String title){
		this.title = title;
	}

	/**
	 * Busca la cancion, si no existe retona false.
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public boolean searchSong() throws UnsupportedEncodingException {
		normalizeArtistTitle();
		String search_link = search_url + this.artist + "+"
				+ this.title.replace(" ", "+") + "&p=0";
		return get_search_result(search_link);
	}

	/**
	 * Metodo de soporte, descarga la pagina html resultante de la b�squeda de
	 * una cancion a partir del nombre del artista y el titulo del tema.
	 */
	public boolean get_search_result(String url) {
		try {
			Pattern patt = Pattern.compile(regular_exp, Pattern.DOTALL
					| Pattern.UNIX_LINES);
			URLEncoder.encode(url, "UTF-8");
			URL u = new URL(url);
			Matcher m = patt.matcher(getURLContent(u));
			if (m.find()) {
				String id = m.group(1).split("/")[1];
				if(getXMLInfo(id))
					return true;
				else
					return false;
			} else {
				return false;
			}
		} catch (MalformedURLException mue) {
			return false;
		} catch (IOException ioe) {
			return false;
		}
	}

	/**
	 * Metodo de soporte, descarga una pagina html y la convierte a CharSequence
	 */
	private final CharSequence getURLContent(URL url) throws IOException {
		URLConnection conn = url.openConnection();
		String encoding = conn.getContentEncoding();

		if (encoding == null) {
			encoding = "ISO-8859-1";
		}

		BufferedReader br = new BufferedReader(new InputStreamReader(conn
				.getInputStream(), encoding));
		StringBuilder sb = new StringBuilder(16384);

		try {
			String line;
			while ((line = br.readLine()) != null) {
				sb.append(line);
				sb.append('\n');
			}
		} finally {
			br.close();
		}
		return sb;
	}

	/**
	 * Metodo de soporte, setea los atributos a partir del archivo xml de la
	 * cancion buscada.
	 */
	private final boolean getXMLInfo(String id) throws IOException {
		GoearXMLHandler xmlpath = new GoearXMLHandler(id);
		if(xmlpath.get_search_result()){
			this.mp3_url = xmlpath.getMp3_path();
			return true;
		}
		else
			return false;
	}
	
	/**
	 * Metodo para normalizar los posibles caracteres "extraños" que puedan
	 * aparecer en los nombres de artistas/canciones y que dificultan la búsqueda
	 * en la web.
	 */
	private final void normalizeArtistTitle(){
		artist = artist.replaceAll("á","a");
		artist = artist.replaceAll("é","e");
		artist = artist.replaceAll("í", "i");
		artist = artist.replaceAll("ó","o");
		artist = artist.replaceAll("ú","u");
		artist = artist.replaceAll("&","");
		artist = artist.replaceAll(" ", "+");
		
		title = title.replaceAll("á","a");
		title = title.replaceAll("é","e");
		title = title.replaceAll("í", "i");
		title = title.replaceAll("ó","o");
		title = title.replaceAll("ú","u");
		title = title.replaceAll("&","");
		title = title.replaceAll(" ", "+");
	}

	/**
	 * Retorna el link directo al archivo mp3.
	 * @return String
	 */
	public String getMp3_url() {
		return mp3_url;
	}

	@Override
	public String toString() {
		return this.artist + " - " + this.title;
	}

}
